package club.xyes.zkh.ecommerce.web.api.controller;

import club.xyes.zkh.ecommerce.commons.dto.MinimalUserInfo;
import club.xyes.zkh.ecommerce.commons.entity.*;
import club.xyes.zkh.ecommerce.commons.properties.WebsiteConfigurationProperties;
import club.xyes.zkh.ecommerce.commons.util.EntityImagePathUtils;
import club.xyes.zkh.ecommerce.commons.vo.GeneralCollectionResult;
import club.xyes.zkh.ecommerce.commons.vo.GeneralResult;
import club.xyes.zkh.ecommerce.service.*;
import club.xyes.zkh.ecommerce.service.listener.OnUserMembershipLevelChangedListener;
import club.xyes.zkh.ecommerce.service.util.UserMembershipFunctions;
import club.xyes.zkh.ecommerce.web.controller.BaseController;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Create by 郭文梁 2019/4/18 0018 14:51
 * UserMembershipController
 * 用户会员等级相关数据访问控制器
 *
 * @author 郭文梁
 * @data 2019/4/18 0018
 */
@RestController
@RequestMapping("/api/user-membership")
public class UserMembershipController extends BaseController<UserMembership> {
    private final ShopService shopService;
    private final UserMembershipService service;
    private final UserService userService;
    private final TransactionLogService transactionLogService;
    private final ShopMembershipLevelService shopMembershipLevelService;
    private final WebsiteConfigurationProperties websiteConfigurationProperties;
    private final OnUserMembershipLevelChangedListener onUserMembershipLevelChangedListener;

    @Autowired
    public UserMembershipController(UserMembershipService service,
                                    ShopService shopService,
                                    UserService userService,
                                    TransactionLogService transactionLogService,
                                    ShopMembershipLevelService shopMembershipLevelService,
                                    WebsiteConfigurationProperties websiteConfigurationProperties,
                                    OnUserMembershipLevelChangedListener onUserMembershipLevelChangedListener) {
        super(service);
        this.service = service;
        this.shopService = shopService;
        this.userService = userService;
        this.transactionLogService = transactionLogService;
        this.shopMembershipLevelService = shopMembershipLevelService;
        this.websiteConfigurationProperties = websiteConfigurationProperties;
        this.onUserMembershipLevelChangedListener = onUserMembershipLevelChangedListener;
    }

    /**
     * 获取当前用户的会员等级定义
     *
     * @return GeneralResult
     */
    @ApiOperation("获取当前用户的会员等级")
    @GetMapping("/mine")
    public GeneralCollectionResult<UserMembership> mine() {
        @NotNull MinimalUserInfo userInfo = getRequiredUserInfo();
        Integer userId = userInfo.getUserId();
        String serverPrefix = websiteConfigurationProperties.getStaticServerPrefix();
        String logoFilePath = websiteConfigurationProperties.getShopLogoPath();
        String membershipImagePath = websiteConfigurationProperties.getShopMembershipImagePath();
        List<UserMembership> memberships = service.findByUserIdFetchAll(userId)
                .stream().peek(v -> {
                    ShopMembershipLevel level = v.getLevel();
                    if (level != null) {
                        ShopMembership membership = level.getMembership();
                        Integer shopId = membership.getShopId();
                        Shop shop = shopService.getRequired(shopId);
                        EntityImagePathUtils.prettyLogoPath(shop, serverPrefix, logoFilePath);
                        membership.setShop(shop);
                        EntityImagePathUtils.prettyShopMembershipImagePath(membership, serverPrefix, membershipImagePath);
                    }
                }).collect(Collectors.toList());
        return GeneralCollectionResult.ok(memberships);
    }

    /**
     * 查询当前用户指定商户的会员卡
     *
     * @param shopId 商铺ID
     * @return 会员卡信息
     */
    @ApiOperation("查询当前用户指定商户的会员卡")
    @GetMapping("/mine/shop/{shopId}")
    public GeneralCollectionResult<UserMembership> mine(@PathVariable("shopId") Integer shopId) {
        @NotNull MinimalUserInfo userInfo = getRequiredUserInfo();
        Integer userId = userInfo.getUserId();
        List<UserMembership> memberships = service.findByUserIdAndShopIdFetchAll(userId, shopId);
        return GeneralCollectionResult.ok(memberships);
    }

    /**
     * 注册会员（刷新会员等级）
     *
     * @param shopId 商铺ID
     * @return GR with UserMembership
     */
    @ApiOperation("刷新会员等级")
    @PostMapping("/shop/{shopId}/_refresh-level")
    public GeneralResult<UserMembership> refreshLevel(@PathVariable("shopId") Integer shopId) {
        Shop shop = shopService.getRequired(shopId);
        User user = userService.getRequired(getRequiredUserInfo().getUserId());
        ShopMembershipLevel level = UserMembershipFunctions.getLevel(user, shop, transactionLogService, shopMembershipLevelService);
        UserMembership res = service.register(user, shop, level, onUserMembershipLevelChangedListener);
        if (res == null) {
            return GeneralResult.badRequest("Unqualified");
        }
        return GeneralResult.ok(res);
    }

    /**
     * 设置用户会员信息
     *
     * @param userId 用户ID
     * @param param  (membershipLevelId:1)
     * @return GR
     */
    @ApiOperation("设置用户的会员等级")
    @PostMapping("/user/{userId}/set-level")
    public GeneralResult<UserMembership> setUserLevel(@PathVariable("userId") Integer userId,
                                                      @RequestBody UserMembership param) {
        if (param == null || param.getMembershipLevelId() == null) {
            return GeneralResult.badRequest("缺少参数");
        }
        Shop shop = currentShop(shopService);
        User user = userService.getRequired(userId);
        ShopMembershipLevel level = shopMembershipLevelService.getRequired(param.getMembershipLevelId());
        UserMembership res = service.register(user, shop, level, onUserMembershipLevelChangedListener);
        return GeneralResult.ok(res);
    }
}
